
package com.wyzz.hr.bo.impl;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Pattern;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.FetchMode;
import org.hibernate.criterion.*;
import org.springframework.util.ObjectUtils;

import com.wyzz.hr.base.Status;
import com.wyzz.hr.bo.IAttendmonthlyBO;
import com.wyzz.hr.bo.ILeavecalendarBO;
import com.wyzz.hr.dao.IAttenddailyDAO;
import com.wyzz.hr.pojo.Attendmonthly;
import com.wyzz.hr.pojo.Attendperiod;
import com.wyzz.hr.pojo.Employee;
import com.wyzz.hr.pojo.Empsalarypay;
import com.wyzz.hr.pojo.Leaverequest;
import com.wyzz.hr.pojo.Overtimerequest;
import com.wyzz.hr.pojo.base.BaseAttendmonthly;
import com.wyzz.hr.shift.AttendDailyHandler;
import com.wyzz.hr.support.AttendDailyMemory;
import com.wyzz.hr.support.AttendmonthlyFactory;
import com.wyzz.hr.util.DatabaseSysConfigManager;
import com.wyzz.hr.util.DateUtil;
import com.wyzz.hr.util.Pager;


public class AttendmonthlyBOImpl implements IAttendmonthlyBO, Status {

	public AttendmonthlyBOImpl() {
	}

	public boolean addAttendmonthly(Attendmonthly attendmonthly) {
		attenddailyDAO.saveObject(attendmonthly);
		return true;
	}

	public boolean deleteAttendmonthly(String ids) {
		String hql = (new StringBuilder()).append(
				"delete from Attendmonthly where id in (").append(ids).append(
				")").toString();
		attenddailyDAO.exeHql(hql);
		return true;
	}

	public boolean exeMonthlySummary(String yearMonth) {
		yearMonth = yearMonth.replaceAll("-", "");
		deleteAttendmonthlyByDate(yearMonth);
		List monthly = importAttendmonthlyData(yearMonth, new String[0]);
		saveAttendmonthlyData(monthly);
		saveInitStatus(yearMonth);
		return true;
	}

	public List exeMonthlySummary(String yearMonth, String empIds[]) {
		yearMonth = yearMonth.replaceAll("-", "");
		return importAttendmonthlyData(yearMonth, empIds);
	}

	private List getEmpListByDate(Date startDate, Date endDate) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Employee.class);
		detachedCriteria.add(Restrictions.le(Employee.PROP_EMP_JOIN_DATE,
				endDate));
		detachedCriteria.add(Restrictions.or(Restrictions.eq(
				Employee.PROP_EMP_STATUS, Integer.valueOf(1)), Restrictions
				.and(Restrictions.eq(Employee.PROP_EMP_STATUS, Integer
						.valueOf(0)), Restrictions.ge(
						Employee.PROP_EMP_TERMINATE_DATE, startDate))));
		List empList = attenddailyDAO.findByCriteria(detachedCriteria);
		return empList;
	}

	private List getEmpListByIds(String empIds[]) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Employee.class);
		detachedCriteria.add(Restrictions.in(Employee.PROP_ID, empIds));
		List empList = attenddailyDAO.findByCriteria(detachedCriteria);
		return empList;
	}

	private void saveInitStatus(String yearMonth) {
		Attendperiod period = new Attendperiod();
		period = new Attendperiod();
		period.setAttpYearmonth(yearMonth);
		period.setAttpStatus(new Integer(0));
		attenddailyDAO.saveObject(period);
	}

	protected List importAttendmonthlyData(String yearMonth, String empIds[]) {
		Map dbConfigMap = DatabaseSysConfigManager.getInstance()
				.getProperties();
		Date dateArr[] = ExaminDateUtil.getDateArray(yearMonth,
				(String) dbConfigMap.get("sys.examin.month.sum"));
		Date startDate = dateArr[0];
		Date endDate = dateArr[1];
		String latePeriodConfig = (String) dbConfigMap
				.get("sys.shift.late.minute");
		String earlyPeriodConfig = (String) dbConfigMap
				.get("sys.shift.earlyleave.minute");
		latePeriodConfig = getDbConfProp(
				latePeriodConfig,
				"^\\d+\\,\\d+\\;((\\d+\\,\\d+)|(\\s*))\\;((\\d+\\,\\d+)|(\\s*))",
				"5,15;15,30;30,90");
		earlyPeriodConfig = getDbConfProp(
				earlyPeriodConfig,
				"^\\d+\\,\\d+\\;((\\d+\\,\\d+)|(\\s*))\\;((\\d+\\,\\d+)|(\\s*))",
				"5,15;15,30;30,90");
		List empList = null;
		if (empIds == null || empIds.length == 0)
			empList = getEmpListByDate(startDate, endDate);
		else
			empList = getEmpListByIds(empIds);
		AttendDailyHandler handler = new AttendDailyHandler();
		handler.setEmpList(empList);
		handler.setStartDate(startDate);
		handler.setEndDate(endDate);
		List daily = handler.generateRecords();
		Map resultMap = initAttendMonthlyMap(empList, yearMonth);
		String empId = null;
		Iterator i$ = daily.iterator();
		do {
			if (!i$.hasNext())
				break;
			AttendDailyMemory mem = (AttendDailyMemory) i$.next();
			empId = mem.getEmpId();
			Attendmonthly monthly = (Attendmonthly) resultMap.get(empId);
			if (monthly != null) {
				computeLrAndOr(monthly, mem);
				monthly.setAttmDutyDays(monthly.getAttmDutyDays().add(
						mem.getOughtDutyDays()));
				monthly.setAttmOffDutyDays(monthly.getAttmOffDutyDays().add(
						mem.getAbsentDays()));
				BigDecimal leaveDay = mem.getLeaveDays();
				BigDecimal onDuty = mem.getOughtDutyDays().subtract(
						mem.getAbsentDays()).subtract(leaveDay);
				monthly.setAttmOnDutyDays(monthly.getAttmOnDutyDays().add(
						onDuty));
				monthly.setAttmDutyHours(monthly.getAttmDutyHours().add(
						mem.getOughtDutyHours()));
				monthly.setAttmOffDutyHours(monthly.getAttmOffDutyHours().add(
						mem.getAbsentHours()));
				BigDecimal leaveHour = mem.getLeaveHours();
				BigDecimal onDutyHours = mem.getOughtDutyHours().subtract(
						mem.getAbsentHours()).subtract(leaveHour);
				monthly.setAttmOnDutyHours(monthly.getAttmOnDutyHours().add(
						onDutyHours));
				monthly.setAttmLateTimes(monthly.getAttmLateTimes().add(
						ExaminDateUtil.getExaminDatePeriod(
								mem.getLateMinutes(), latePeriodConfig)));
				monthly.setAttmEarlyLeave(monthly.getAttmEarlyLeave().add(
						ExaminDateUtil.getExaminDatePeriod(mem
								.getEarlyMinutes(), earlyPeriodConfig)));
				resultMap.put(empId, monthly);
			}
		} while (true);
		List result = new ArrayList();
		Object key;
		for (i$ = resultMap.keySet().iterator(); i$.hasNext(); result
				.add(resultMap.get(key)))
			key = (String) i$.next();

		return result;
	}

	private void computeLrAndOr(Attendmonthly attdm, AttendDailyMemory mem) {
		Map leaveHoursMap = mem.getLeaveHoursMap();
		Map leaveDaysMap = mem.getLeaveDaysMap();
		AttendmonthlyFactory.initAttendMonthlyProperties(attdm);
		if (leaveHoursMap.get(Integer.valueOf(0)) != null) {
			attdm.setAttmLeaveCasualHours(attdm.getAttmLeaveCasualHours().add(
					(BigDecimal) leaveHoursMap.get(Integer.valueOf(0))));
			attdm.setAttmLeaveCasualDays(attdm.getAttmLeaveCasualDays().add(
					(BigDecimal) leaveDaysMap.get(Integer.valueOf(0))));
		}
		if (leaveHoursMap.get(Integer.valueOf(1)) != null) {
			attdm.setAttmLeaveAnnualHours(attdm.getAttmLeaveAnnualHours().add(
					(BigDecimal) leaveHoursMap.get(Integer.valueOf(1))));
			attdm.setAttmLeaveAnnualDays(attdm.getAttmLeaveAnnualDays().add(
					(BigDecimal) leaveDaysMap.get(Integer.valueOf(1))));
		}
		if (leaveHoursMap.get(Integer.valueOf(3)) != null) {
			attdm.setAttmLeaveSickHours(attdm.getAttmLeaveSickHours().add(
					(BigDecimal) leaveHoursMap.get(Integer.valueOf(3))));
			attdm.setAttmLeaveSickDays(attdm.getAttmLeaveSickDays().add(
					(BigDecimal) leaveDaysMap.get(Integer.valueOf(3))));
		}
		if (leaveHoursMap.get(Integer.valueOf(4)) != null) {
			attdm.setAttmLeaveSick01Hours(attdm.getAttmLeaveSick01Hours().add(
					(BigDecimal) leaveHoursMap.get(Integer.valueOf(4))));
			attdm.setAttmLeaveSick01Days(attdm.getAttmLeaveSick01Days().add(
					(BigDecimal) leaveDaysMap.get(Integer.valueOf(4))));
		}
		if (leaveHoursMap.get(Integer.valueOf(5)) != null) {
			attdm.setAttmLeaveSick02Hours(attdm.getAttmLeaveSick02Hours().add(
					(BigDecimal) leaveHoursMap.get(Integer.valueOf(5))));
			attdm.setAttmLeaveSick02Days(attdm.getAttmLeaveSick02Days().add(
					(BigDecimal) leaveDaysMap.get(Integer.valueOf(5))));
		}
		if (leaveHoursMap.get(Integer.valueOf(6)) != null) {
			attdm.setAttmLeaveWeddingHours(attdm.getAttmLeaveWeddingHours()
					.add((BigDecimal) leaveHoursMap.get(Integer.valueOf(6))));
			attdm.setAttmLeaveWeddingDays(attdm.getAttmLeaveWeddingDays().add(
					(BigDecimal) leaveDaysMap.get(Integer.valueOf(6))));
		}
		if (leaveHoursMap.get(Integer.valueOf(7)) != null) {
			attdm.setAttmLeaveMaternityHours(attdm.getAttmLeaveMaternityHours()
					.add((BigDecimal) leaveHoursMap.get(Integer.valueOf(7))));
			attdm.setAttmLeaveMaternityDays(attdm.getAttmLeaveMaternityDays()
					.add((BigDecimal) leaveDaysMap.get(Integer.valueOf(7))));
		}
		if (leaveHoursMap.get(Integer.valueOf(8)) != null) {
			attdm.setAttmLeaveTravelHours(attdm.getAttmLeaveTravelHours().add(
					(BigDecimal) leaveHoursMap.get(Integer.valueOf(8))));
			attdm.setAttmLeaveTravelDays(attdm.getAttmLeaveTravelDays().add(
					(BigDecimal) leaveDaysMap.get(Integer.valueOf(8))));
		}
		if (leaveHoursMap.get(Integer.valueOf(9)) != null) {
			attdm.setAttmLeaveOuterHours(attdm.getAttmLeaveOuterHours().add(
					(BigDecimal) leaveHoursMap.get(Integer.valueOf(9))));
			attdm.setAttmLeaveOuterDays(attdm.getAttmLeaveOuterDays().add(
					(BigDecimal) leaveDaysMap.get(Integer.valueOf(9))));
		}
		if (leaveHoursMap.get(Integer.valueOf(11)) != null) {
			attdm.setAttmLeaveTiaoxiu01Hours(attdm.getAttmLeaveTiaoxiu01Hours()
					.add((BigDecimal) leaveHoursMap.get(Integer.valueOf(11))));
			attdm.setAttmLeaveTiaoxiu01Days(attdm.getAttmLeaveTiaoxiu01Days()
					.add((BigDecimal) leaveDaysMap.get(Integer.valueOf(11))));
		}
		if (leaveHoursMap.get(Integer.valueOf(20)) != null) {
			attdm.setAttmLeaveOtherHours(attdm.getAttmLeaveOtherHours().add(
					(BigDecimal) leaveHoursMap.get(Integer.valueOf(20))));
			attdm.setAttmLeaveOtherDays(attdm.getAttmLeaveOtherDays().add(
					(BigDecimal) leaveDaysMap.get(Integer.valueOf(20))));
		}
		if (mem.getLeaveHours() != null) {
			attdm.setAttmLeaveHours(attdm.getAttmLeaveHours().add(
					mem.getLeaveHours()));
			attdm.setAttmLeaveDays(attdm.getAttmLeaveDays().add(
					mem.getLeaveDays()));
		}
		Map orHoursMap = mem.getOrHoursMap();
		BigDecimal bd = new BigDecimal(0);
		Iterator i$ = orHoursMap.keySet().iterator();
		do {
			if (!i$.hasNext())
				break;
			String key = (String) i$.next();
			bd = bd.add((BigDecimal) orHoursMap.get(key));
			if (key.equals("03"))
				attdm.setAttmOtHolidayHours(attdm.getAttmOtHolidayHours().add(
						(BigDecimal) orHoursMap.get(key)));
			else if (key.equals("02"))
				attdm.setAttmOtWeekendHours(attdm.getAttmOtWeekendHours().add(
						(BigDecimal) orHoursMap.get(key)));
			else if (key.equals("01"))
				attdm.setAttmOtNormalHours(attdm.getAttmOtNormalHours().add(
						(BigDecimal) orHoursMap.get(key)));
		} while (true);
		attdm.setAttmOvertimeHours(bd);
	}

	private boolean saveAttendmonthlyData(List monthlyList) {
		Iterator i$ = monthlyList.iterator();
		do {
			if (!i$.hasNext())
				break;
			Attendmonthly monthly = (Attendmonthly) i$.next();
			Employee emp = monthly.getAttmEmpId();
			if (emp != null) {
				monthly.setAttmDept(emp.getEmpDeptNo());
				monthly.setAttmLocation(emp.getEmpLocationNo());
				monthly.setAttmEmptype(emp.getEmpType());
				monthly.setAttmPbNo(emp.getEmpPbNo());
			}
		} while (true);
		attenddailyDAO.saveOrupdate(monthlyList);
		return true;
	}

	private String getDbConfProp(String str, String regex, String defaultStr) {
		if (StringUtils.isEmpty(str))
			return defaultStr;
		boolean match = Pattern.matches(regex, str);
		if (!match)
			return defaultStr;
		else
			return str;
	}

	protected List getLeaveRequest(Date startDate, Date endDate, List empList) {
		Calendar toDate = Calendar.getInstance();
		toDate.setTime(endDate);
		toDate.add(5, 1);
		DetachedCriteria detachedCrteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leaverequest.class);
		detachedCrteria.setFetchMode("lrLtNo", FetchMode.JOIN);
		detachedCrteria.add(Restrictions.or(Restrictions.or(Restrictions.and(
				Restrictions.ge(Leaverequest.PROP_LR_START_DATE, startDate),
				Restrictions.lt(Leaverequest.PROP_LR_START_DATE, toDate
						.getTime())), Restrictions.and(Restrictions.lt(
				Leaverequest.PROP_LR_END_DATE, toDate.getTime()), Restrictions
				.ge(Leaverequest.PROP_LR_END_DATE, startDate))), Restrictions
				.and(Restrictions
						.lt(Leaverequest.PROP_LR_START_DATE, startDate),
						Restrictions.ge(Leaverequest.PROP_LR_END_DATE, toDate
								.getTime()))));
		detachedCrteria.add(Restrictions.in(Leaverequest.PROP_LR_STATUS,
				new Integer[] { Integer.valueOf(15), Integer.valueOf(16) }));
		if (empList.size() > 0)
			detachedCrteria.add(Restrictions.in("lrEmpNo", empList));
		return attenddailyDAO.findByCriteria(detachedCrteria);
	}

	protected List getOvertimeRequest(Date startDate, Date endDate, List empList) {
		DetachedCriteria detachedCrteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Overtimerequest.class);
		detachedCrteria.setFetchMode("orOtNo", FetchMode.JOIN);
		detachedCrteria.add(Restrictions.and(Restrictions.ge(
				Overtimerequest.PROP_OR_SHIFT_DATE, startDate), Restrictions
				.le(Overtimerequest.PROP_OR_SHIFT_DATE, endDate)));
		detachedCrteria.add(Restrictions.in("orStatus", new Integer[] {
				Integer.valueOf(15), Integer.valueOf(16) }));
		if (empList.size() > 0 && empList.size() <= 500)
			detachedCrteria.add(Restrictions.in("orEmpNo", empList));
		return attenddailyDAO.findByCriteria(detachedCrteria);
	}

	public Attendmonthly getAttendmonthly(String id) {
		return (Attendmonthly) attenddailyDAO.loadObject(
				com.wyzz.hr.pojo.Attendmonthly.class, id, null, new boolean[0]);
	}

	public List searchAttendmonthly(Pager page, DetachedCriteria dc) {
		List result;
		if (page == null)
			result = attenddailyDAO.findByCriteria(dc);
		else
			result = attenddailyDAO.findByCriteria(dc, page.getPageSize(), page
					.getCurrentPage());
		return result;
	}

	public Attendperiod loadAttendperiod(String yearMonth) {
		yearMonth = yearMonth.replaceAll("-", "");
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendperiod.class);
		detachedCriteria.add(Restrictions.eq(Attendperiod.PROP_ATTP_YEARMONTH,
				yearMonth));
		List list = attenddailyDAO.findByCriteria(detachedCriteria);
		if (list.size() > 0)
			return (Attendperiod) list.get(0);
		else
			return null;
	}

	public Integer getAttpStatus(String yearMonth) {
		Attendperiod attp = loadAttendperiod(yearMonth);
		if (attp != null)
			return attp.getAttpStatus();
		else
			return null;
	}

	public List getClosedPeriod(String startYearMonth, String endYearMonth) {
		String hql = (new StringBuilder()).append(
				"select attpYearmonth from Attendperiod where ").append(
				Attendperiod.PROP_ATTP_YEARMONTH).append(">='").append(
				startYearMonth).append("' and ").append(
				Attendperiod.PROP_ATTP_YEARMONTH).append("<='").append(
				endYearMonth).append("' and attpStatus=2").toString();
		List list = attenddailyDAO.exeHqlList(hql);
		return list;
	}

	public boolean saveOrUpdateAttmList(List attmList) {
		attenddailyDAO.saveOrupdate(attmList);
		return true;
	}

	public boolean deleteAttendmonthlyByDate(String yearMonth) {
		String hql = (new StringBuilder()).append(
				"delete from Attendmonthly where ").append(
				Attendmonthly.PROP_ATTM_YEARMONTH).append(" = '").append(
				yearMonth).append("'").toString();
		attenddailyDAO.exeHql(hql);
		String sql = (new StringBuilder()).append(
				"delete from Attendperiod where ").append(
				Attendperiod.PROP_ATTP_YEARMONTH).append(" = '").append(
				yearMonth).append("'").toString();
		attenddailyDAO.exeHql(sql);
		return true;
	}

	public Attendmonthly saveOrUpdateAttendmonthly(Attendmonthly attend,
			String mode) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendmonthly.class);
		detachedCriteria.add(Restrictions.eq(Attendmonthly.PROP_ATTM_YEARMONTH,
				attend.getAttmYearmonth()));
		detachedCriteria.add(Restrictions.eq(Attendmonthly.PROP_ATTM_EMP_ID,
				attend.getAttmEmpId()));
		List result = attenddailyDAO.findByCriteria(detachedCriteria);
		if (result == null || result.size() <= 0) {
			AttendmonthlyFactory.initAttendMonthlyProperties(attend);
			attenddailyDAO.saveObject(attend);
			Attendperiod period = new Attendperiod();
			period.setAttpYearmonth(attend.getAttmYearmonth());
			period.setAttpStatus(Integer.valueOf(0));
			attenddailyDAO.saveObject(period);
			return attend;
		}
		Attendmonthly attendFromDB = (Attendmonthly) result.get(0);
		AttendmonthlyFactory.initAttendMonthlyProperties(attend);
		AttendmonthlyFactory.initAttendMonthlyProperties(attendFromDB);
		attendFromDB.setAttmLateTimes(attend.getAttmLateTimes());
		attendFromDB.setAttmEarlyLeave(attend.getAttmEarlyLeave());
		attendFromDB.setAttmAbsentDays(attend.getAttmAbsentDays());
		attendFromDB.setAttmAbsentHours(attend.getAttmAbsentHours());
		String dayConf = DatabaseSysConfigManager.getInstance().getProperty(
				"sys.examin.leave.mode");
		BigDecimal hourPerday = new BigDecimal(dayConf);
		if ("0".equals(mode)) {
			attendFromDB.setAttmDutyDays(attend.getAttmDutyDays());
			attendFromDB.setAttmOnDutyDays(attend.getAttmOnDutyDays());
			attendFromDB.setAttmOffDutyDays(attend.getAttmOffDutyDays());
			attendFromDB
					.setAttmLeaveAnnualDays(attend.getAttmLeaveAnnualDays());
			attendFromDB.setAttmLeaveTiaoxiu01Days(attend
					.getAttmLeaveTiaoxiu01Days());
			attendFromDB
					.setAttmLeaveCasualDays(attend.getAttmLeaveCasualDays());
			attendFromDB.setAttmLeaveMaternityDays(attend
					.getAttmLeaveMaternityDays());
			attendFromDB.setAttmLeaveOtherDays(attend.getAttmLeaveOtherDays());
			attendFromDB.setAttmLeaveSickDays(attend.getAttmLeaveSickDays());
			attendFromDB
					.setAttmLeaveSick01Days(attend.getAttmLeaveSick01Days());
			attendFromDB
					.setAttmLeaveSick02Days(attend.getAttmLeaveSick02Days());
			attendFromDB
					.setAttmLeaveTravelDays(attend.getAttmLeaveTravelDays());
			attendFromDB.setAttmLeaveOuterDays(attend.getAttmLeaveOuterDays());
			attendFromDB.setAttmLeaveWeddingDays(attend
					.getAttmLeaveWeddingDays());
			BigDecimal attmLeaveDays = AttendmonthlyFactory
					.calculateLeaveTotalDays(attend);
			attendFromDB.setAttmLeaveDays(attmLeaveDays);
			shiftDaysOrHours(attendFromDB, "dayToHour", hourPerday);
		} else {
			attendFromDB.setAttmDutyHours(attend.getAttmDutyHours());
			attendFromDB.setAttmOnDutyHours(attend.getAttmOnDutyHours());
			attendFromDB.setAttmOffDutyHours(attend.getAttmOffDutyHours());
			attendFromDB.setAttmLeaveAnnualHours(attend
					.getAttmLeaveAnnualHours());
			attendFromDB.setAttmLeaveTiaoxiu01Hours(attend
					.getAttmLeaveTiaoxiu01Hours());
			attendFromDB.setAttmLeaveCasualHours(attend
					.getAttmLeaveCasualHours());
			attendFromDB.setAttmLeaveMaternityHours(attend
					.getAttmLeaveMaternityHours());
			attendFromDB
					.setAttmLeaveOtherHours(attend.getAttmLeaveOtherHours());
			attendFromDB.setAttmLeaveSickHours(attend.getAttmLeaveSickHours());
			attendFromDB.setAttmLeaveSick01Hours(attend
					.getAttmLeaveSick01Hours());
			attendFromDB.setAttmLeaveSick02Hours(attend
					.getAttmLeaveSick02Hours());
			attendFromDB.setAttmLeaveTravelHours(attend
					.getAttmLeaveTravelHours());
			attendFromDB
					.setAttmLeaveOuterHours(attend.getAttmLeaveOuterHours());
			attendFromDB.setAttmLeaveWeddingHours(attend
					.getAttmLeaveWeddingHours());
			BigDecimal attmLeaveHours = AttendmonthlyFactory
					.calculateLeaveTotalHours(attend);
			attendFromDB.setAttmLeaveHours(attmLeaveHours);
			shiftDaysOrHours(attendFromDB, "hourToDay", hourPerday);
		}
		attendFromDB.setAttmOtHolidayHours(attend.getAttmOtHolidayHours());
		attendFromDB.setAttmOtNormalHours(attend.getAttmOtNormalHours());
		attendFromDB.setAttmOtWeekendHours(attend.getAttmOtWeekendHours());
		attendFromDB.setAttmOvertimeHours(AttendmonthlyFactory
				.calculateOtTotalHours(attend));
		attendFromDB.setAttmField01(attend.getAttmField01());
		attendFromDB.setAttmField02(attend.getAttmField02());
		attendFromDB.setAttmField03(attend.getAttmField03());
		attendFromDB.setAttmField04(attend.getAttmField04());
		attendFromDB.setAttmField05(attend.getAttmField05());
		attendFromDB.setAttmField06(attend.getAttmField06());
		attendFromDB.setAttmField07(attend.getAttmField07());
		attendFromDB.setAttmField08(attend.getAttmField08());
		attendFromDB.setAttmField09(attend.getAttmField09());
		attendFromDB.setAttmField10(attend.getAttmField10());
		attendFromDB.setAttmField11(attend.getAttmField11());
		attendFromDB.setAttmField12(attend.getAttmField12());
		attendFromDB.setAttmField13(attend.getAttmField13());
		attendFromDB.setAttmField14(attend.getAttmField14());
		attendFromDB.setAttmField15(attend.getAttmField15());
		attendFromDB.setAttmField16(attend.getAttmField16());
		attendFromDB.setAttmField17(attend.getAttmField17());
		attendFromDB.setAttmField18(attend.getAttmField18());
		attendFromDB.setAttmField19(attend.getAttmField19());
		attendFromDB.setAttmField20(attend.getAttmField20());
		attendFromDB.setAttmField21(attend.getAttmField21());
		attendFromDB.setAttmField22(attend.getAttmField22());
		attendFromDB.setAttmField23(attend.getAttmField23());
		attendFromDB.setAttmField24(attend.getAttmField24());
		attendFromDB.setAttmComments(attend.getAttmComments());
		attenddailyDAO.updateObject(attendFromDB);
		return attendFromDB;
	}

	public void updateObject(Object object) {
		attenddailyDAO.updateObject(object);
	}

	public void saveObject(Object obj) {
		attenddailyDAO.saveObject(obj);
	}

	public boolean setAttmByPay(String yearMonth, Empsalarypay payArray[]) {
		if (ObjectUtils.isEmpty(payArray))
			return false;
		Integer attpStatus = getAttpStatus(yearMonth);
		if (attpStatus == null || attpStatus.intValue() != 2)
			return false;
		DetachedCriteria dc = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendmonthly.class);
		if (payArray.length < 500) {
			Set empIds = new HashSet();
			Empsalarypay arr$[] = payArray;
			int len$ = arr$.length;
			for (int i$ = 0; i$ < len$; i$++) {
				Empsalarypay pay = arr$[i$];
				empIds.add(pay.getEspEmpno().getId());
			}

			dc.add(Restrictions.in((new StringBuilder()).append(
					Attendmonthly.PROP_ATTM_EMP_ID).append(".").append(
					Employee.PROP_ID).toString(), empIds));
		}
		dc.add(Restrictions.eq(Attendmonthly.PROP_ATTM_YEARMONTH, yearMonth));
		List attendmonthList = attenddailyDAO.findByCriteria(dc);
		if (attendmonthList.size() == 0)
			return false;
		Map monthly = new HashMap();
		Attendmonthly attendmonthly;
		for (Iterator i$ = attendmonthList.iterator(); i$.hasNext(); monthly
				.put(attendmonthly.getAttmEmpId().getId(), attendmonthly))
			attendmonthly = (Attendmonthly) i$.next();

		Empsalarypay arr$[] = payArray;
		int len$ = arr$.length;
		for (int i$ = 0; i$ < len$; i$++) {
			Empsalarypay pay = arr$[i$];
			Attendmonthly attendMonthly = (Attendmonthly) monthly.get(pay
					.getEspEmpno().getId());
			pay.setAttendMonthly(attendMonthly);
		}

		return true;
	}

	protected Map initAttendMonthlyMap(List empList, String yearMonth) {
		Map result = new HashMap();
		Employee emp;
		Attendmonthly monthly;
		for (Iterator i$ = empList.iterator(); i$.hasNext(); result.put(emp
				.getId(), monthly)) {
			emp = (Employee) i$.next();
			monthly = AttendmonthlyFactory.createAttendMonthly();
			monthly.setAttmEmpId(emp);
			monthly.setAttmYearmonth(yearMonth);
		}

		return result;
	}

	public List getEmpMonthlyOfYear(List empList, String year) {
		String yearMonthStart = (new StringBuilder()).append(year).append("00")
				.toString();
		String yearMonthEnd = (new StringBuilder()).append(
				Integer.parseInt(year) + 1).append("00").toString();
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendmonthly.class);
		detachedCriteria.add(Restrictions.in(Attendmonthly.PROP_ATTM_EMP_ID,
				empList));
		detachedCriteria.add(Restrictions.gt(Attendmonthly.PROP_ATTM_YEARMONTH,
				yearMonthStart));
		detachedCriteria.add(Restrictions.lt(Attendmonthly.PROP_ATTM_YEARMONTH,
				yearMonthEnd));
		List result = attenddailyDAO.findByCriteria(detachedCriteria);
		return result;
	}

	public void shiftDaysOrHours(Attendmonthly month, String shiftMode,
			BigDecimal hourPerday) {
		String dayFiledFlag = "Days";
		String hourFieldFlag = "Hours";
		Class cls = BaseAttendmonthly.class;
		Field fieldlist[] = cls.getDeclaredFields();
		for (int i = 0; i < fieldlist.length; i++) {
			Field field = fieldlist[i];
			String fieldName = field.getName();
			if (fieldName.indexOf("Days") < 0 && fieldName.indexOf("Hours") < 0
					|| fieldName.indexOf("attmOt") > -1
					|| fieldName.equals("attmOvertimeHours"))
				continue;
			if ("dayToHour".equals(shiftMode)) {
				if (fieldName.indexOf("Days") <= -1)
					continue;
				String fieldNameHour = fieldName.replace("Days", "Hours");
				try {
					BigDecimal dayValue = (BigDecimal) PropertyUtils
							.getProperty(month, fieldName);
					if (dayValue != null)
						PropertyUtils.setProperty(month, fieldNameHour,
								dayValue.multiply(hourPerday));
				} catch (Exception e) {
					e.printStackTrace();
				}
				continue;
			}
			if (!"hourToDay".equals(shiftMode)
					|| fieldName.indexOf("Hours") <= -1)
				continue;
			String fieldNameDay = fieldName.replace("Hours", "Days");
			try {
				BigDecimal hourValue = (BigDecimal) PropertyUtils.getProperty(
						month, fieldName);
				if (hourValue != null)
					PropertyUtils.setProperty(month, fieldNameDay, hourValue
							.divide(hourPerday, 4, 2));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	public List getAllYears() {
		Integer endYear = Integer.valueOf(DateUtil.getYear(new Date()));
		Integer startYear = endYear;
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendperiod.class);
		List yearmonth = attenddailyDAO.findByCriteria(detachedCriteria
				.setProjection(Projections.distinct(Projections
						.min(Attendperiod.PROP_ATTP_YEARMONTH))));
		if (yearmonth != null && yearmonth.size() > 0
				&& StringUtils.isNotEmpty((String) yearmonth.get(0))) {
			Integer tmpYear = Integer.decode(((String) yearmonth.get(0))
					.substring(0, 4));
			if (tmpYear.intValue() < startYear.intValue())
				startYear = tmpYear;
		}
		List year = new ArrayList();
		for (Integer i = startYear; i.intValue() <= endYear.intValue();) {
			year.add(i.toString());
			Integer integer = i;
			Integer integer1 = i = Integer.valueOf(i.intValue() + 1);
			Integer _tmp = integer;
		}

		return year;
	}

	public boolean deleteAttendmonthly(Attendmonthly attendmonthly) {
		attenddailyDAO.deleteObject(attendmonthly);
		return true;
	}

	public IAttenddailyDAO getAttenddailyDAO() {
		return attenddailyDAO;
	}

	public void setAttenddailyDAO(IAttenddailyDAO attenddailyDAO) {
		this.attenddailyDAO = attenddailyDAO;
	}

	public ILeavecalendarBO getLc_BO() {
		return lc_BO;
	}

	public void setLc_BO(ILeavecalendarBO lc_BO) {
		this.lc_BO = lc_BO;
	}

	public LrDataCheckImpl getLrDataCheck() {
		return lrDataCheck;
	}

	public void setLrDataCheck(LrDataCheckImpl lrDataCheck) {
		this.lrDataCheck = lrDataCheck;
	}

	private static final String DEFAULT_LATE_MINUTE_CONFIT = "5,15;15,30;30,90";
	private static final String DEFAULT_EARLY_LEAVE_CONFIG = "5,15;15,30;30,90";
	private static final String EARLY_LEAVE_AND_LATE_CONFIG_REG = "^\\d+\\,\\d+\\;((\\d+\\,\\d+)|(\\s*))\\;((\\d+\\,\\d+)|(\\s*))";
	protected IAttenddailyDAO attenddailyDAO;
	protected ILeavecalendarBO lc_BO;
	protected LrDataCheckImpl lrDataCheck;
}
